<?php

namespace app\api\controller;
use app\admin\controller\image;
use app\common\controller\Api;
use PHPMailer\PHPMailer\PHPMailer;
use think\Db;
/**
 * 小程序端 数据接口
 */
class Data extends Api
{

    // 无需登录的接口,*表示全部
    protected $noNeedLogin = ['test','getHouse', 'getHotels','getHdetail','paytype','moneyLog','getRdetail','baseinfo','chongzhi','getopenid','getPrePay','wxlogin','wxxml','wxxmlchongzhi','submitDrawBack',
        "orderlist",'getchongzhi',"prevOrderDetail","makeOrder","cancelOrder","cancelfeeOrder","order_fee","confirmCheckout","order_drawback","notifyUrl",'getmoney',"order_detail","getuser","updateuser",'ifmobile','upmobile','xiaoxituisong','sendduanxin','access_token','userNoPay','cancelOrdertest'];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = ['test'];

    protected $mainhost = "";
    protected $mhotel = "";
    protected $mhouse = "";
    protected $muser = "";

    public function __construct(){
        parent::__construct();
        $this->mainhost = "http://".$_SERVER["HTTP_HOST"];
        $this->mhotel = model("hotels");
        $this->mhouse = model("house");
        $this->muser = model("user");
        $this->morder = model("order");
    }


    //测试方法
    public function test(){
        $total_fee = 215800;
        $score = round($total_fee/100, 2);

        $uid = 3;
        $res = updateLevel($score,$uid);

        var_dump($res);die;

    }

    public function paytype(){
        $uid = $this->request->request("uid");
        $pay = $this->request->request("paymoney");
        $res=array(
            'money'=>0,
            'card'=>0,
        );
        $m=db('user')->where("id = $uid")->find();
        $res['yue']=$m['money'];
        if($m['money']>= $pay){
            $res['money']=1;
        }
        $this->success('success',$res);
    }



    public function getchongzhi(){
        $m=db('config')->where("id = 35")->find();
        $this->success('success',$m['value']);
    }


    public function moneyLog(){

        $uid = $this->request->request("uid");
      $m=db('user_money_log')->where("user_id = $uid")->select();

      foreach ($m as $k => $v){
          $m[$k]['createtime']=date('Y-m-d H:i:s',$v['createtime']);
      }

      $this->success('success',$m);
    }

    //检查用户是否有未支付订单
    public function userNoPay(){
        $uid = $this->request->request("uid");
        $count = db("order")->where(["user_id"=>$uid,"pay_status"=>0])->count("id");

        $this->success("未支付订单个数",$count,0);

    }



    public function getuser(){
        $uid = $this->request->request("uid");
        $m=db('user')->where("id = $uid")->find();
        if($m){
            $this->success("success",$m);
        }else{
            $this->error('没找到该用户');
        }
    }

    public function updateuser(){
        $uid = $this->request->request("uid");
        $data['idcard'] = $this->request->request("idcard");
        $data['birthday'] = $this->request->request("birthday");
        $data['phone'] = $this->request->request("phone");
        $data['ftype'] = $this->request->request("ftype");


        $m=db('user')->where("id = $uid")->update($data);
        if($m){
            $this->success("success",$m);
        }else{
            $this->error('更新失败');
        }
    }


    //首页地图 获取酒店数据和酒店下房源数据
    public function getHotels(){


        $lng1 = $this->request->request("lng");
        $lat1 = $this->request->request("lat");

        if(empty($lng1) || empty($lat1)){
            $this->error('经纬度参数错误');
        }


        $list = $this->mhotel->where("h_status='normal'")->field("hid as id,h_title as name,h_status,h_img,h_address,lng as longitude,lat as latitude")->select();

        $templist = [];
        foreach ($list as $k=>&$v){
            //获取酒店房源
            $v["roomlist"] = $this->getHrooms($v["id"]);
            $v["type"] = count($v["roomlist"]);
            if($v["type"] != 0){ //排除没有房源的酒店
                $v["h_img"] = $this->mainhost.$v["h_img"];
                $v["h_address"] = subText3($v["h_address"],13);
                $v["distance"] = getdistance($lng1,$lat1,$v["longitude"],$v["latitude"]);
                $sort[] = $v["distance"];
                $templist[$k] = $v;
            }

        }

        array_multisort($sort,SORT_ASC,$templist);

        $count = count($templist);
        if($count > 5){
            $templist = array_slice($templist,0,5);
        }


        if($templist){
            $this->success("success",$templist);
        }else{
            $this->error();
        }

    }


    public function wxloginwmc(){
        $data = $_GET;

        $openid = $data['openid'];
        $data['ctime'] = date('Y-m-d H:i:s', time());
        $m = db('wxuser')->where("openid = '$openid'")->find();

        if ($m) {
            $id=$m['id'];
            $this->success(__('successful'), $id);

        }else{
            $id = db('wxuser')->insertGetId($data);
            $this->success(__('successful'), $id);
        }
    }

    //微信授权登录后 写入fa_user表
    public function wxlogin(){
        $data = $_GET;
        $openid = $data['openid'];
        $data['ctime'] = date('Y-m-d H:i:s', time());
        $info = db('user')->where(["openid"=>$openid])->find();


        //已注册
        if ($info) {


            $id=$info['id'];
            $this->success(__('successful'), $id);

        }else{
            //未注册
            $data["from"] = 1;
            $data["group_id"] = 2;//默认用户组


            $id = db('user')->insertGetId($data);
            $this->success(__('successful'), $id);
        }

    }


    //支付 获取真实金额
    public function getPrePay(){
        $openid = $this->request->request("openid");
        $ordernum = $this->request->request("ordernum");

        //获取订单金额数据

        $info = db("order")->where(["order_number"=>$ordernum])->field("order_number,all_money,payend_time")->find();

        if($info["payend_time"] < time()){
            echo 456;die;
        }


        if(!$info){
            $this->error("订单数据有误");
        }


        //$price= 0.05 * 100;//测试 一分钱
        $price=$info["all_money"] * 100;  //真实需要支付的金额
        $out_trade_no = $info["order_number"];  //订单号
        $PrePay = WxPay::PrePay($out_trade_no,$openid,$price);  //统一下单

        if($PrePay["return_code"]=="FAIL"){
            /*返回错误*/
            echo 234;die;


        }
        else{
            if(empty($PrePay["prepay_id"])){
                echo 234;die;

            }else{
                $PrePayId=$PrePay["prepay_id"];  // 获取预支付id
                $PaySign=WxPay::getPaySign($PrePayId,$PrePay["nonce_str"]);
                $a= array("prepay_id"=>$PrePayId,"paySign"=>$PaySign["PaySign"],"nonce_str"=>$PrePay["nonce_str"],"timeStamp"=>$PaySign["timeStamp"],"order_no"=>$out_trade_no);
                $this->success('success',$a);
            }

        }
    }



    //支付 充值
    public function chongzhi(){

        $openid = $this->request->request("openid");
        $chongzhijine = $this->request->request("chongzhijine");

        //$price= 0.05 * 100;//测试 一分钱
        $price=$chongzhijine * 100;  //真实需要支付的金额
           $out_trade_no = time().$this->makeCardPassword();  //充值订单号

        $PrePay = WxPay::PrePaychongzhi($out_trade_no,$openid,$price);  //统一下单

        if($PrePay["return_code"]=="FAIL"){
            /*返回错误*/
            echo 234;die;
        }
        else{
            if(empty($PrePay["prepay_id"])){
                echo 234;die;

            }else{
                $PrePayId=$PrePay["prepay_id"];  // 获取预支付id
                $PaySign=WxPay::getPaySign($PrePayId,$PrePay["nonce_str"]);
                $a= array("prepay_id"=>$PrePayId,"paySign"=>$PaySign["PaySign"],"nonce_str"=>$PrePay["nonce_str"],"timeStamp"=>$PaySign["timeStamp"],"order_no"=>$out_trade_no);
                $this->success('success',$a);
            }

        }
    }


    function makeCardPassword() {
        $code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $rand = $code[rand(0,25)]
            .strtoupper(dechex(date('m')))
            .date('d').substr(time(),-5)
            .substr(microtime(),2,5)
            .sprintf('%02d',rand(0,99));
        for(
            $a = md5( $rand, true ),
            $s = '0123456789ABCDEFGHIJKLMNOPQRSTUV',
            $d = '',
            $f = 0;
            $f < 8;
            $g = ord( $a[ $f ] ),
            $d .= $s[ ( $g ^ ord( $a[ $f + 8 ] ) ) - $g & 0x1F ],
            $f++
        );
        return  $d;
    }




    private static function str_rand($length = 32, $char = 'abcdefghijklmnopqrstuvwxyz0123456789') {
        $str ="";
        for ( $i = 0; $i < $length; $i++ )  {
            $str .= substr($char, mt_rand(0, strlen($char)-1), 1);
        }
        return $str;
    }

    //获取酒店下可以出租的房源 以推荐排序 id 次之
    protected function getHrooms($hid){

        $list = $this->mhouse
            ->where("h_statusText='normal'")
            ->where("h_id={$hid}")
            ->field('id as roomid,h_title as roomtitle,h_hot as roomhot,h_price as roomprice,h_attr as roomattr,concat("'.$this->mainhost.'", h_img) as roomimg')
            ->order("h_hot desc,id asc")
            ->select();
        return $list;
    }

    //获取酒店下可以出租的房源 以推荐排序 id 次之
    protected function getHroomsOne($hid){

        $list = $this->mhouse
            ->where("h_statusText='normal'")
            ->where("h_id={$hid}")
            ->field('id as roomid,h_title as roomtitle,h_allprice as allprice,h_hot as roomhot,h_price as roomprice,h_attr as roomattr,concat("'.$this->mainhost.'", h_img) as roomimg')
            ->order("h_hot desc,id asc")
            ->find();

        return $list;

    }


    //获取酒店下可以出租的房源 以推荐排序 id 次之
    protected function getHroomlist($hid)
    {

        $list = $this->mhouse
            ->where("h_statusText='normal'")
            ->where("h_id={$hid}")
            ->field('id as roomid,h_title as roomtitle,h_hot as roomhot,h_price as roomprice,h_attr as roomattr,concat("' . $this->mainhost . '", h_img) as roomimg')
            ->order("h_hot desc,id asc")
            ->select();

        return $list;
    }
    //首页底部推荐房间数据
    public function getHouse(){

        $lng1 = $this->request->request("lng");
        $lat1 = $this->request->request("lat");

        if(empty($lng1) || empty($lat1)){
            $this->error('经纬度参数错误');
        }

        $list = $this->mhotel->where("h_status='normal'")->field("hid,lng,lat")->select();

        $templist = [];
        foreach ($list as $k=>&$v){
            //获取酒店房源
            $v["roominfo"] = $this->getHroomsOne($v["hid"]);
            if($v["roominfo"] != Null){ //排除没有房源的酒店
                //截取字符串
                $v['roominfo']['roomattr'] = subText( $v['roominfo']['roomattr'],15);
                $v["distance"] = getdistance($lng1,$lat1,$v["lng"],$v["lat"]);
                $sort[] = $v["distance"];
                $templist[$k] = $v;
            }

        }

        if($templist){
            array_multisort($sort,SORT_ASC,$templist);
            $count = count($templist);
            if($count > 5){
                $templist = array_slice($templist,0,5);
            }

            $this->success("success",$templist);
        }else{
            $this->error();
        }

    }

    //酒店详情页面
    public function getHdetail(){
        $id = $this->request->request("hid");
        $info = $this->mhotel->where("hid={$id}")->field("hid,h_title,h_tel,h_read,h_servs,h_address,h_content,lng,lat,h_imgs,h_startCount,h_hoteldetail")->find();

        if($info){

            //处理图片
            if($info["h_imgs"]){
                $imgs = array();
                $imgarr = explode(",",$info["h_imgs"]);
                $len = count($imgarr);
                if($len > 1){
                    for ($i=0;$i<$len;$i++){
                        $imgs[$i] = $this->mainhost . $imgarr[$i];
                    }
                }else{
                    $imgs[0] = $this->mainhost . $info["h_imgs"];
                }
                $info["imglist"] = $imgs;
            }else{
                $info["imglist"] = [];

            }
            unset($info["h_imgs"]);
            //处理 酒店设施
            if($info["h_servs"]){
                //获取酒店设备服务
                $res = db('category')->where("type='酒店属性'")->where("id","in",$info["h_servs"])->field("name,nickname,image")->select();

                if($res){
                    foreach ($res as &$v){
                        $v["image"] = $this->mainhost.$v["image"];
                    }
                }


                $info["hservs"]  =$res;

            }else{
                $info["hservs"]  = [];
            }


            unset($info["h_servs"]);


            $info['roomlist'] = $this->getHroomlist($id);


            $this->success("success",$info);
        }else{
            $this->error();
        }
    }

    //房间详情
    public function getRdetail(){
        $id = $this->request->request("id");
        $info = $this->mhouse
            ->where("id={$id}")
            ->join('hotels hl','hl.hid=fa_house.h_id')
            ->field("id,h_id,hl.h_tel,hl.h_address,hl.h_title as htitle,h_housebrand,fa_house.h_storey,fa_house.h_title,fa_house.h_read,fa_house.h_servs,fa_house.h_service,fa_house.h_service2,fa_house.h_content,fa_house.h_imgs,fa_house.h_price,fa_house.h_allprice,fa_house.h_attr")
            ->find();
        if($info){

            //处理图片
            if($info["h_imgs"]){
                $imgs = array();
                $imgarr = explode(",",$info["h_imgs"]);
                $len = count($imgarr);
                if($len > 1){
                    for ($i=0;$i<$len;$i++){
                        $imgs[$i] = $this->mainhost . $imgarr[$i];
                    }
                }else{
                    $imgs[0] = $this->mainhost . $info["h_imgs"];
                }
                $info["imglist"] = $imgs;
            }else{
                $info["imglist"] = [];

            }
            unset($info["h_imgs"]);


            //处理 房间设施
            if($info["h_servs"]){
                //获取酒店设备服务
                $res = db('category')->where("type='房间属性'")->where("id","in",$info["h_servs"])->field("name,nickname,image")->select();

                if($res){
                    foreach ($res as &$v){
                        $v["image"] = $this->mainhost.$v["image"];
                    }
                }


                $info["hservs"]  =$res;

            }else{
                $info["hservs"]  = [];
            }

            unset($info["h_servs"]);

            //字符串转数组 1 2 3 4 基础设施
            if($info['h_service'] !=''){
                //$info['h_service'] = explode(",",$info['h_service']);
                $tmp = explode(",",$info['h_service']);
                $restmp=[];
                for($i=1;$i<5;$i++){
                    if(in_array($i,$tmp)){
                        $restmp[$i][] = 'y';
                    }else{
                        $restmp[$i][] = 'n';
                    }
                    if($i==1){
                        $restmp[$i][] = '无线网';
                    }elseif($i==2){
                        $restmp[$i][] = '电梯';
                    }elseif($i==3){
                        $restmp[$i][] = '落地窗';
                    }else{
                        $restmp[$i][] = '空调';
                    }
                }

                $info['h_service'] = $restmp;

            }else{
                $info['h_service'] = [];
            }

            //字符串转数组 1 2 3 4 卫浴设施
            if($info['h_service2'] !=''){

                $tmp = explode(",",$info['h_service2']);
                $restmp=[];
                for($i=1;$i<5;$i++){
                    if(in_array($i,$tmp)){
                        $restmp[$i][] = 'y';
                    }else{
                        $restmp[$i][] = 'n';
                    }
                    if($i==1){
                        $restmp[$i][] = '热水';
                    }elseif($i==2){
                        $restmp[$i][] = '独立卫浴';
                    }elseif($i==3){
                        $restmp[$i][] = '电吹风';
                    }else{
                        $restmp[$i][] = '洗浴用品';
                    }
                }

                $info['h_service2'] = $restmp;

            }else{
                $info['h_service2'] = [];
            }

            //字符串转数组 1 2 3 4 5 6 7 8  入住须知
            if($info['h_read'] !=''){

                $tmp = explode(",",$info['h_read']);
                $restmp=[];
                for($i=1;$i<9;$i++){
                    if(in_array($i,$tmp)){
                        $restmp[$i][] = 'y';
                    }else{
                        $restmp[$i][] = 'n';
                    }
                    if($i==1){
                        $restmp[$i][] = '接待儿童';
                    }elseif($i==2){
                        $restmp[$i][] = '接待老人';
                    }elseif($i==3){
                        $restmp[$i][] = '接待外宾';
                    }elseif($i==4){
                        $restmp[$i][] = '带宠物';
                    }elseif($i==5){
                        $restmp[$i][] = '吸烟';
                    }elseif($i==6){
                        $restmp[$i][] = '做饭';
                    }elseif($i==7){
                        $restmp[$i][] = '聚会';
                    }else{
                        $restmp[$i][] = '商拍';
                    }
                }

                $info['h_read'] = $restmp;

            }else{
                $info['h_read'] = [];
            }



            //获取基础费用和押金
            $basemoney = model('Config')->where("name='baseprice'")->field("value")->find();
            if($basemoney){
                $tempmoney = $basemoney->toarray()["value"];
                $bList = json_decode($tempmoney,true);
                $info["baseprice"] = $bList["基础费用"];
                $info["deposit"] = $bList["押金"];
            }

            //获取每天时间配置 比如 一天 22小时
            $hreads = model('Config')->where("name='moveinRead'")->field("value")->find();

            if($hreads){
                $hreads = $hreads->toarray()["value"];
                $hreads = json_decode($hreads,true);
                $info["mitime"] = $hreads["入离时间"];
                $info["nodeposit"] = $hreads["无需押金"];
                $info["clean"] = $hreads["清洁费"];
                $info["celrole"] = $hreads["取消规则"];
            }

            $this->success("success",$info);
        }else{
            $this->error();
        }
    }

    //获取手机和修改 身份证
    public function baseinfo(){
        $uid = $this->request->request("uid");
        if(empty($uid)){
            $this->error("参数错误");
        }
        if($this->request->isGet()){
            $info = $this->muser->where("id={$uid}")->field("id,mobile,idcard")->find();
            if($info){
                $this->success("success",$info);
            }else{
                $this->error();
            }
        }

        if($this->request->isPost()){
            $mobile = $this->request->request("mobile");
            if(empty($mobile)){
                $this->error("参数错误");
            }
            $idcard = $this->request->request("idcard");
            $data["mobile"] = $mobile;
            $data["idcard"] = $idcard;
            $data["updatetime"] = time();

            if($this->muser->where("id={$uid}")->update($data)){
                $this->success("更新成功");
            }else{
                $this->error("更新错误");
            }
        }
    }


    //订单相关接口  相关状态如下
    //0 未支付 1 已预定（支付） 2 已入住（支付,待退房状态）3 已完成（支付后，退房，房间回归打扫）
    //4 已取消（未付款，未住，30分钟后，自动取消房间预定，回归空闲，或者后台管理员手动取消，前台用户不能手动取消）
    //5支付失败（房间回归空闲）

    //我的订单 列表
    public function orderlist(){
        $uid = $this->request->request("uid");
        $status = $this->request->request("status");
        $page = $this->request->request("page",1);
        $limit = $this->request->request("limit",5);
        if(!$uid){
            $this->error("uid参数错误");
        }
        if(!in_array($status,[0,1,2,3,4,5])){
            $this->error("状态参数错误");
        }

        $where["user_id"] = $uid;

        try{

            $list = $this->morder
                ->where($where)
                ->where("pay_status",'in',$status)
                ->page($page,$limit)
                ->order("id desc")
                ->select();

            if($list){
                //处理订单数据 方便前端显示
                $reslist = [];
                foreach ($list as $k=>$v){
                    $tmp = [];
                    $tmp["order_number"] = $v["order_number"];
                    $tmp["pay_status"] = $v["pay_status"];
                    $tmp["prepay_id"] = $v["prepay_id"];
                    $roominfo = json_decode($v["room_html"],true);
                    $tmp["roominfo"]["roomid"] = $roominfo["id"];
                    $tmp["roominfo"]["roomimg"] = $this->mainhost . $roominfo["h_img"];
                    $tmp["roominfo"]["roomtitle"] = $roominfo["h_title"];
                    $tmp["roominfo"]["roomattr"] = subText3($roominfo["h_attr"],15);
                    if($v["pay_status"] == 0){
                        $tmp["roominfo"]["statusText"] = "继续支付";
                    }elseif ($v["pay_status"] == 4){
                        $tmp["roominfo"]["statusText"] = "取消时间：".date("Y-m-d H:i:s",$v["cancel_time"]);
                    }elseif ($v["pay_status"] == 3){
                        $tmp["roominfo"]["statusText"] = "结算时间：".date("Y-m-d H:i:s",$v["checkout_time"]);
                    }elseif ($v["pay_status"] == 5){
                        $tmp["roominfo"]["statusText"] = "下单时间：".date("Y-m-d H:i:s",$v["add_time"]);
                    }elseif ($v["pay_status"] == 1){
                        $tmp["roominfo"]["statusText"] = "入住时间：".date("Y-m-d H:i:s",$v["stime"]);
                    }elseif ($v["pay_status"] == 2){
                        $tmp["roominfo"]["statusText"] = "退房结算";
                    }else{
                        $tmp["roominfo"]["statusText"] = "订单状态异常，联系客服";
                    }
                    $reslist[$k] = $tmp;
                }

                $this->success("success",$reslist);
            }else{
                $this->success("暂无数据",[]);
            }
        }catch (\think\exception\PDOException $e){
            $this->error($e->getMessage());
        }

    }

    // 订单待支付页面数据 已经创建了订单数据
    public function prevOrderDetail(){
        $id = $this->request->request("id");
        $where["id"] = $id;
        $where["h_statusText"] = "normal";

        //获取房子详情
        try{
            $info = $this->mhouse->where($where)->find();
            if($info){
                $this->success("success",$info);
            }else{
                $this->error("房源紧张，被抢走了");
            }
        }catch (\think\exception\PDOException $e){
            $this->error($e->getMessage());
        }
    }

    //生成订单 => 进入 待支付页面 此时不会修改房源状态 支付成功后根据预定的开始时间前两个小时 才修改房源状态为 预定
    //逻辑，如果预定时间在两个小时内，那就直接修改为预定状态，如果超过两个小时，那就定时任务去遍历订单，如果时间到了两个小时内，就自动改成已经预定
    //在用户预定房间的时间前两个小时的时间 仍然可以预定，所以，再次预定房间的人最晚可以预定到下个预定房间前两个小时，所以，要对订单里有没有预定房间 预定时间进行判断，
    //目前只判断预定房间前的时间是否可以被再次预定，不考虑预定结束后的房间是否可以预定，因为会出现多种情况，比如，打扫时间、维修等，或者房间延时等，所以不接受预定房间后的房间被预定的情况，
    //除非入住结束，房间回到空闲状态可以进行预定。

    public function makeOrder(){

        $id = $this->request->request("id");
        $uid = $this->request->request("uid");
        $stime = $this->request->request("stime");
        $etime = $this->request->request("etime");

        //用户如果没有选择结束日期，默认第二天12点
        if(empty($id) || empty($uid) || empty($stime)){
            $this->error("参数错误");
        }

        $nowMonth = date("m",time());
        //获取今年
        $year = date("Y",time());
        //获取明年
        $tyear = date('Y', strtotime("+1 year"));

        $stimeArr = explode(" ",$stime);
        $stimeArr2 = explode("-",$stimeArr[0]);
        $stimeArr3 = explode(":",$stimeArr[1]);

        if($stimeArr2[0] < 10){
            //判断开始时间是否跨年
            $sMonth = "0".(int)$stimeArr2[0];
        }else{
            $sMonth = $stimeArr2[0];
        }

        if($stimeArr2[1] < 10){
            $sDay = "0".(int)$stimeArr2[1];
        }else{
            $sDay = $stimeArr2[1];
        }

        if($stimeArr3[0] < 10){
            $sHour = "0".(int)$stimeArr3[0];
        }else{
            $sHour = $stimeArr3[0];
        }

        if($stimeArr3[1] < 10){
            $sMin = "0".(int)$stimeArr3[1];
        }else{
            $sMin = $stimeArr3[1];
        }

        //格式化开始时间   //获取开始时间
        if((int)$stimeArr2[0] >= $nowMonth){
            //今年
            $stime = $year."-".$sMonth."-".$sDay." ".$sHour.":".$sMin;
        }else{
            //明年
            $stime = $tyear."-".$sMonth."-".$sDay." ".$sHour.":".$sMin;
        }
        //开始时间
        $intstime = strtotime($stime);


        if($etime){

            //结束时间 判断是否跨年
            $etimeArr = explode(" ",$etime);
            $etimeArr2 = explode("-",$etimeArr[0]);
            $etimeArr3 = explode(":",$etimeArr[1]);

            if($etimeArr2[0] < 10){
                $eMonth = "0".(int)$etimeArr2[0];
            }else{
                $eMonth = $etimeArr2[0];
            }

            if($etimeArr2[1] < 10){
                $eDay = "0".(int)$etimeArr2[1];
            }else{
                $eDay = $etimeArr2[1];
            }

            if($etimeArr3[0] < 10){
                $eHour = "0".(int)$etimeArr3[0];
            }else{
                $eHour = $etimeArr3[0];
            }

            if($etimeArr3[1] < 10){
                $eMin = "0".(int)$etimeArr3[1];
            }else{
                $eMin = $etimeArr3[1];
            }

            //格式化开始时间
            if((int)$etimeArr2[0] >= $nowMonth){
                //今年
                $etime = $year."-".$eMonth."-".$eDay." ".$eHour.":".$eMin;
            }else{
                //明年
                $etime = $tyear."-".$eMonth."-".$eDay." ".$eHour.":".$eMin;
            }

            //结束时间
            $intetime = strtotime($etime);


            if($intstime >= $intetime ){
                $this->error("结束时间必须大于开始时间");
            }

            if($intetime - $intstime < 3600){
                $this->error("请至少预定一小时");
            }

        }else{
            $intetime = strtotime(date('Y-m-d',($intstime)));
            $intetime += 129600;//次日12点
        }

        $where["id"] = $id;
        $where["h_statusText"] = "normal";

        //判断房源是否可以被预定 正常情况，返回房间数据
        $info = $this->checkHouseStatus($id,$uid,$intetime);

        try{

            if($info){
                //储存房源信息 订单参数配置 获取基础费用
                $res = model('Config')->where("name='ordercofig'")->field("value")->find();
                if($res){
                    $restmp = $res->toarray()["value"];
                    $orderconfig = json_decode($restmp,true);

                }else{
                    $this->error("订单参数配置有误，请联系管理员");
                }

                $res = model('Config')->where("name='baseprice'")->field("value")->find();
                if($res){
                    $restmp = $res->toarray()["value"];
                    $orderbase = json_decode($restmp,true);

                }else{
                    $this->error("基础费用配置有误，请联系管理员");
                }

                //计算房费 定时 和 非定时计算房费
                $datainfo["hourDaily"] = $orderconfig["每天时长"];
                $datainfo["totalprice"] = $info["h_allprice"];
                $datainfo["price"] = $info["h_price"];
                $datainfo["overtimeMinute"] = $orderconfig["超分算时"]; //超过多少分钟算作一小时
                $datainfo["cancelpay_time"] = $orderconfig["免费取消时间"]; //支付成功后免费取消时间 单位：分
                $datainfo["sendmsg_time"] = $orderconfig["到期提醒"]; //房费结束发送时间
                $datainfo["bprice"] = $orderbase["基础费用"];
                $datainfo["deposit"] = $orderbase["押金"];
                $datainfo["intetime"] = $intetime;
                $datainfo["intstime"] = $intstime;

                if($etime){ //定时计算房费
                    $compRes = $this->computeFeeHour($datainfo); //定时房费的计算逻辑
                    //定时数据搜集
                    $orderData["timing"] = 0;
                    $orderData["cancelpay_time"] = $compRes["cancelpay_time"];
                    $orderData["sendmsg_time"] = $compRes["sendmsg_time"];
                    $orderData["income"] = $compRes["income"]; //订单收入 根据退房时动态计算
                    $orderData["all_price"] = $compRes["all_price"]; //房费
                    $orderData["ballprice"] = $compRes["ballprice"]; //基础保障总费用
                    $orderData["return_money"] = $compRes["return_money"]; //退款金额
                    $orderData["all_money"] =  $compRes["all_money"];// 创建定时订单时，房费为根据时间计算 所以，这里的总金额是 基础费用 + 押金 + 房费
                    $orderData["moveinto_time"] =  $intstime; //定时订单 入住时间 就是预定开始的时间 后端手动改房源为入住，则修改此时间

                }else{ //非定时计算房费 只要计算押金和基础费用即可 无需计算房费
                    $orderData["timing"] = 1;
                    $orderData["cancelpay_time"] = time() + $datainfo["cancelpay_time"] * 60;//免费取消时间
                    $orderData["sendmsg_time"] = $intetime - $datainfo["sendmsg_time"] * 60;//发送房间到期时间
                    $orderData["income"] = $orderbase["基础费用"]; //订单收入 非定时订单创建时收入为0 根据退房时动态计算
                    $orderData["all_price"] = 0;//房费 创建时房费为0
                    $orderData["ballprice"] = $orderbase["基础费用"];
                    $orderData["return_money"] = $orderbase["押金"]; //退款金额 只是押金
                    $orderData["all_money"] = $orderbase["基础费用"] + $orderbase["押金"];
                    $orderData["moveinto_time"] =  $intstime + $orderconfig["计费时间"] * 60; //非定时订单 入住时间 就是预定开始的时间 + 计费开始时间moveintoTime 取配置的值  后端手动改房源为入住，则修改此时间
                }

                $orderData["overtimeminute"] = $orderconfig["超分算时"];
                $orderData["stime"] = $intstime;
                $orderData["etime"] = $intetime;
                $orderData["room_html"] = json_encode($info);
                $orderData["room_id"] = $id;
                $orderData["hotelid"] = $info["h_id"]; //酒店id
                $orderData["user_id"] = $uid;
                $orderData["order_number"] = date("YmdHis", time()) . rand(10000000, 99999999);
                $orderData["price"] = $info["h_price"];
                $orderData["totalprice"] = $info["h_allprice"];
                $orderData["bprice"] = $orderbase["基础费用"];
                $orderData["deposit"] =  $orderbase["押金"];
                $orderData["add_time"] =  time();
                $orderData["payend_time"] =  time() + $orderconfig["支付时间"] * 60; //单位秒
                $orderData["pay_status"] =  0;//为支付

                //获取酒店电话
                $hinfo = db("hotels")->where(["hid"=>$info["h_id"]])->field("h_phone")->find();
                //获取用户手机号
                $uinfo = db("user")->where(["id"=>$uid])->field("phone,nickName")->find();
                $orderData["h_phone"] =  $hinfo["h_phone"];
                $orderData["user_phone"] =  $uinfo["phone"];
                $orderData["user_name"] =  $uinfo["nickName"];
                $orderData["sendmsg_flag"] =  1;

                if($this->morder->insert($orderData)){
                    $this->success("success",$orderData["order_number"]);
                }else{
                    $this->error("订单生成失败");
                }

            }else{
                $this->error("房源紧张，被抢走了");
            }
        }catch (\think\exception\PDOException $e){
            $this->error($e->getMessage());
        }
    }

    public function order_detail(){
        $order_number = $this->request->request("order_number");
        if(empty($order_number)){
            $this->error("参数错误");
        }

        $where["order_number"] =$order_number;
        //获取订单信息
        $info = $this->morder->where($where)->find();
        // print_r($info);die;
        if($info){
            $roominfo = json_decode($info['room_html'],true);

            //返回给前端数据 检索请求
            $resdata["payendTime"] =  $info["payend_time"];
            $resdata["order_number"] =  $info["order_number"];
            $resdata["price"] =  $info["price"];
            $resdata["bprice"] =  $info["bprice"];
            $resdata["deposit"] =  $info["deposit"];
            $resdata["roomimg"] = $this->mainhost . $roominfo["h_img"];
            $resdata["roomtitle"] =  $roominfo["h_title"];
            $resdata["roomtiming"] =  date("Y-m-d H:i:s",$info["moveinto_time"]);

            $this->success("success",$resdata);
        }else{
            $this->error("订单数据错误");
        }


    }

    //取消订单 用户主动取消 分为两个层面 ，支付之前取消 只改变订单状态 支付后取消 改变订单状态和房源状态 和房源可预定时间 同时 如果超过了 取消时间 则扣费用 比例*房源总价格
    public function cancelOrdertest(){

        $order_number = $this->request->request("order_number");

        $uid = $this->request->request("uid");

        if(empty($order_number) || empty($uid)){
            $this->error("参数错误");
        }
        $where["user_id"] = $uid;
        $where["order_number"] =$order_number;
        //获取订单信息
        $info = $this->morder->where($where)->find();


        if($info){
            //根据订单状态判断操作
            if($info["pay_status"] == 0){ //未支付订单取消 退款额 为 总付款 （基础保障费 + 押金 + 房费）不用执行退款
                $updata["pay_status"] = 4;
                $updata["cancel_time"] = time();
                $updata["return_money"] = $info['all_money'];
                if($this->morder->where("id={$info['id']}")->update($updata)){
                    $this->success("订单取消成功");
                }else{
                    $this->error("订单取消失败");
                }
            }elseif($info["pay_status"] == 1){

                //判断是否在允许范围内取消
                $cancelpay_time =  $info["cancelpay_time"];
                $time = time();
                //考虑取消订单后  房源可预定时间的调整
                Db::startTrans();
                //判断是否除了当前订单，是否有其他预定中的订单 如当前订单状态改变为  3 已完成 4 已取消 5 支付失败 等情况下，将可预定状态退回靠近最早的状态
                $otherOrder = db("order")->where(["pay_status"=>1,"room_id"=>$info["room_id"]])->where("order_number != {$info['order_number']}")->order("stime asc ")->find();

                if($otherOrder){
                    //计算开始时间的前两个小时
                    $nowbeforeTime = $otherOrder["stime"] - 7200;
                }else{
                    $nowbeforeTime = Null;
                }

                $updata["pay_status"] = 4;
                $updata["cancel_time"] = time();

                $money = 0;

                //判断是否 取消收费
                if($time > $cancelpay_time) {//收费
                    $res = model('Config')->where("name='discount'")->field("value")->find();
                    if ($res) {
                        $restmp = $res->toarray()["value"];
                        $orderconfig = json_decode($restmp, true);
                    }
                    if ($orderconfig) {
                        $money = $info["totalprice"] * $orderconfig;
                    } else {
                        $money = $info["totalprice"] * 0.1;
                    }
                    $money = sprintf("%01.2f", $money);
                }

                //准备退款数据
                //执行退款
                $refund_number = "refund_".date("YmdHis", time()) . rand(10000000, 99999999);
                $updata["upd_time"] = time();
                $updata["refund_number"] = $refund_number;
                $updata["refund_status"] = 2;//申请退款中
                $eff1 = $this->morder->where("id={$info['id']}")->update($updata);




                //修改房源未空闲
                $rdata["h_statusText"] = "normal";
                $rdata["updatetime"] = time();
                $rdata["beforeTime"] = $nowbeforeTime; //更新可预定时间
                $eff2 = $this->mhouse->where("id={$info['room_id']}")->update($rdata);



                $remoney = $info["return_money"] + $info["ballprice"] - $money;

                $remoney = 0.04 ;
                $all_money = 0.05;

                //$refundRes = $this->submitDrawBackFun($all_money,$remoney ,$info["order_number"],$refund_number,$info["transaction_id"],$info['user_id']);
                //$refundRes = $this->submitDrawBackFun($info["all_money"],$remoney ,$info["order_number"],$refund_number,$info["transaction_id"],$info['user_id']);




                //#todo 这里理论上还应该考虑 退款后 积分回退的逻辑，暂时先不考虑
                if (1==1) {
                    // file_put_contents("refundsuc.json",var_export($refundRes,true));
                    //退款成功 修改订单状态
                    $updata2["refund_status"] = 3;
                    $updata2["pay_status"] = 4;//已经取消
                    $updata2["upd_time"] = time();
                    $updata2["income"] = $money;

                    $eff3 = db("order")->where(["id"=>$info["id"]])->update($updata2);




                    if($eff1 && $eff2 && $eff3){



                        //取消成功后发送短信
                        //发送酒店
                        if($info["h_phone"] && $info["user_name"]){

                            sendmsgHCancel($info["h_phone"],$info["user_name"],$money);
                        }



                        //发送给用户
                        if($info["user_phone"] && $info["h_phone"]){

                            sendmsgUCancel($info["user_phone"],$money,$info["h_phone"]);
                        }



                        Db::commit();
                        $this->success("订单取消成功,退款成功，请核实");
                    }else{
                        Db::rollback();
                        $this->error("订单取消失败");
                    }

                }else{
                    file_put_contents("refunderr.json",var_export($refundRes,true). PHP_EOL,FILE_APPEND);
                    $msg = "退款失败";
                    Db::rollback();
                    $this->error($msg);
                }



            }elseif($info['pay_status'] == 2){
                $this->error("您已入住，不能取消");
            }elseif($info['pay_status'] == 4){
                $this->error("您已经取消了订单！");
            }


        }else{
            $this->error("找不到订单");
        }



    }

    //取消订单 用户主动取消 分为两个层面 ，支付之前取消 只改变订单状态 支付后取消 改变订单状态和房源状态 和房源可预定时间 同时 如果超过了 取消时间 则扣费用 比例*房源总价格
    public function cancelOrder(){

        $order_number = $this->request->request("order_number");

        $uid = $this->request->request("uid");

        if(empty($order_number) || empty($uid)){
            $this->error("参数错误");
        }
        $where["user_id"] = $uid;
        $where["order_number"] =$order_number;
        //获取订单信息
        $info = $this->morder->where($where)->find();


        if($info){
            //根据订单状态判断操作
            if($info["pay_status"] == 0){ //未支付订单取消 退款额 为 总付款 （基础保障费 + 押金 + 房费）不用执行退款
                $updata["pay_status"] = 4;
                $updata["cancel_time"] = time();
                $updata["return_money"] = $info['all_money'];
                if($this->morder->where("id={$info['id']}")->update($updata)){
                    $this->success("订单取消成功");
                }else{
                    $this->error("订单取消失败");
                }
            }elseif($info["pay_status"] == 1){

                //判断是否在允许范围内取消
                $cancelpay_time =  $info["cancelpay_time"];
                $time = time();
                //考虑取消订单后  房源可预定时间的调整
                Db::startTrans();
                //判断是否除了当前订单，是否有其他预定中的订单 如当前订单状态改变为  3 已完成 4 已取消 5 支付失败 等情况下，将可预定状态退回靠近最早的状态
                $otherOrder = db("order")->where(["pay_status"=>1,"room_id"=>$info["room_id"]])->where("order_number != {$info['order_number']}")->order("stime asc ")->find();

                if($otherOrder){
                    //计算开始时间的前两个小时
                    $nowbeforeTime = $otherOrder["stime"] - 7200;
                }else{
                    $nowbeforeTime = Null;
                }

                $updata["pay_status"] = 4;
                $updata["cancel_time"] = time();

                $money = 0;

                //判断是否 取消收费
                if($time > $cancelpay_time) {//收费
                    $res = model('Config')->where("name='discount'")->field("value")->find();
                    if ($res) {
                        $restmp = $res->toarray()["value"];
                        $orderconfig = json_decode($restmp, true);
                    }
                    if ($orderconfig) {
                        $money = $info["totalprice"] * $orderconfig;
                    } else {
                        $money = $info["totalprice"] * 0.1;
                    }
                    $money = sprintf("%01.2f", $money);
                }

                //准备退款数据
                //执行退款
                $refund_number = "refund_".date("YmdHis", time()) . rand(10000000, 99999999);
                $updata["upd_time"] = time();
                $updata["refund_number"] = $refund_number;
                $updata["refund_status"] = 2;//申请退款中
                $eff1 = $this->morder->where("id={$info['id']}")->update($updata);
                //修改房源未空闲
                $rdata["h_statusText"] = "normal";
                $rdata["updatetime"] = time();
                $rdata["beforeTime"] = $nowbeforeTime; //更新可预定时间
                $eff2 = $this->mhouse->where("id={$info['room_id']}")->update($rdata);
                $remoney = $info["return_money"] + $info["ballprice"] - $money;

                // $remoney = 0.04 ;
                //$all_money = 0.05;

                //$refundRes = $this->submitDrawBackFun($all_money,$remoney ,$info["order_number"],$refund_number,$info["transaction_id"],$info['user_id']);
                $refundRes = $this->submitDrawBackFun($info["all_money"],$remoney ,$info["order_number"],$refund_number,$info["transaction_id"],$info['user_id']);

                file_put_contents("refund.json",var_export($refundRes,true).PHP_EOL,FILE_APPEND);


                //#todo 这里理论上还应该考虑 退款后 积分回退的逻辑，暂时先不考虑
                if ($refundRes['RETURN_CODE'] == 'SUCCESS' && $refundRes['RESULT_CODE'] == 'SUCCESS') {
                    file_put_contents("refundsuc.json",var_export($refundRes,true));
                    //退款成功 修改订单状态
                    $updata2["refund_status"] = 3;
                    $updata2["pay_status"] = 4;//已经取消
                    $updata2["upd_time"] = time();
                    $updata2["income"] = $money;

                    $eff3 = db("order")->where(["id"=>$info["id"]])->update($updata2);

                    if($eff1 && $eff2 && $eff3){
                        //取消成功后发送短信
                        //发送酒店
                        if($info["h_phone"] && $info["user_name"]){
                            sendmsgHCancel($info["h_phone"],$info["user_name"],$money);
                        }
                        //发送给用户
                        if($info["user_phone"] && $info["h_phone"]){
                            sendmsgUCancel($info["user_phone"],$money,$info["h_phone"]);
                        }

                        Db::commit();
                        $this->success("订单取消成功,退款成功，请核实");
                    }else{
                        Db::rollback();
                        $this->error("订单取消失败");
                    }

                }else{
                    file_put_contents("refunderr.json",var_export($refundRes,true).PHP_EOL,FILE_APPEND);
                    $msg = "退款失败";
                    Db::rollback();
                    $this->error($msg);
                }



            }elseif($info['pay_status'] == 2){
                $this->error("您已入住，不能取消");
            }elseif($info['pay_status'] == 4){
                $this->error("您已经取消了订单！");
            }


        }else{
            $this->error("找不到订单");
        }



    }




    //封装退款方法 复制后台退款代码
    //退款开始
    public function submitDrawBackFun($all_money,$return_money,$out_trade_no,$refund_number,$transaction_id,$user_id){


        //通过微信api进行退款流程
        $nonce_str = WxPay::str_rand();//随机32位字符串


        $total_fee = $all_money * 100;//总金额，单位：分

        //$total_fee= 0.01 * 100;//测试 一分钱

        //$refund_fee= 0.01 * 100;//测试 一分钱
        $refund_fee = $return_money * 100;//退款金额，单位：分



        $parma = array(
            'appid'=> WxPay::appid,
            'mch_id'=> WxPay::mch_id,
            'nonce_str'=> $nonce_str,
            'out_trade_no'=> $out_trade_no,//小程序自定义订单号，支付时后台生成
            'out_refund_no'=> $refund_number,
            'total_fee'=> $total_fee,
            'refund_fee'=> $refund_fee,
            'transaction_id' => $transaction_id,//小程序平台订单号，微信平台生成
        );


        $KEY = WxPay::key;//小程序支付秘钥
        $parma['sign'] = $this->getSign($parma, $KEY);

        $post_xml = $this->arrayToXml($parma);//把参数转化成xml格式

        //向微信平台api发送退款参数
        $xmlresult = $this->postXmlSSLCurl($post_xml,'https://api.mch.weixin.qq.com/secapi/pay/refund');

        //解析返回的参数
        $array = $this->xml2array($xmlresult);
        //两个success表示退款成功，无需使用回调，在此进行逻辑处理即可

        return $array;

    }


    //退房说明 分定时订单退款 和 不定时退款
    public function order_fee(){
        $order_number = $this->request->request("order_number");
        $uid = $this->request->request("uid");

        if(empty($order_number) || empty($uid)){
            $this->error("参数错误");
        }
        $where["user_id"] = $uid;
        $where["order_number"] = $order_number;
        $where["pay_status"] = 2;//入住的房间才可以计算费用
        $info = $this->morder->where($where)->find();


        if($info){
            $info = $info->toArray();
        }else{
            $this->error("订单数据有误");
        }


        if($info){
            $info["explain"] = "暂无说明";
            //获取退房说明信息
            //储存房源信息 订单参数配置 获取基础费用
            try{
                $res = model('Config')->where("name='checkOutExplain'")->field("value")->find();
                if($res){
                    $restmp = $res->toarray()["value"];
                    if(!empty($restmp)){
                        $info["explain"] = $restmp;
                    }
                }

                //计算房费 定时订单和非定时订单 计算房费不一样
                if($info["timing"] == 1){
                    //如果是非定时订单，则根据实际住的小时数，技术房费，然后从押金和 基础费用总和中扣除，如果不够，线下付款客服，后台管理端做记录入口；
                    $feedata = $this->computeFeeOrderTwo($info);


                }else{

                    //如果定时订单 正常退房，就直接退款 押金 ,基础保障费则不退 如果超时了，就再扣除超时费用后 再退回费用（少于原来的 押金 ）

                    $feedata =  $this->computeFeeOrder($info);
                }

                $feedata["upd_time"] = time();
                $feedata["checkout_time"] = time();

                //更新数据
                if($this->morder->where("id={$info['id']}")->update($feedata)){
                    unset($feedata["upd_time"]);
                    unset($feedata["all_money"]);
                    $feedata["order_number"] = $info["order_number"];
                    $feedata["explain"] = $info["explain"];
                    //新增返回押金
                    $feedata["deposit"] = $info["deposit"];
                    $this->success("费用计算成功",$feedata);
                }else{
                    $this->error("费用计算有误");
                }

            }catch (\think\exception\PDOException $e){
                $this->error($e->getMessage());
            }

        }else{
            $this->error("订单有误");
        }

    }

    public function getopenid()
    {

        $data = $_GET;
        $js_code = $data['js_code'];
        $appid='wxd3ed1291e43598cd';
        $appSecret='3c112f9dced28d11507ea034efa3d099';
        $grant_type='authorization_code';
        $getUrl='https://api.weixin.qq.com/sns/jscode2session?appid=wxd3ed1291e43598cd&secret=3c112f9dced28d11507ea034efa3d099&js_code='.$js_code.'&grant_type=authorization_code';

        $ch = curl_init();

        curl_setopt( $ch , CURLOPT_URL, $getUrl );
        curl_setopt( $ch , CURLOPT_HEADER, 0);

        curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1);
//        curl_setopt( $ch , CURL_SSLVERSION_SSL, 2);
        curl_setopt( $ch , CURLOPT_SSL_VERIFYPEER, FALSE);

        curl_setopt( $ch , CURLOPT_SSL_VERIFYHOST, FALSE);


        $data = curl_exec( $ch );

        $response = json_decode( $data );
        $a= $response ->openid;
        $this->success($a);

    }


    //确认退房
    //todo 需要后台执行退款接口，归还费用 如果押金不够房费 则提示退房失败 联系客服 也可以再次唤起支付 从新付款(去掉押金后的，需要补交的钱，这期先不考虑)
    public function confirmCheckout(){

        $order_number = $this->request->request("order_number");
        $uid = $this->request->request("uid");

        if(empty($order_number) || empty($uid)){
            $this->error("参数错误");
        }

        $where["user_id"] = $uid;
        $where["order_number"] = $order_number;
        $where["pay_status"] = 2;//入住的房间才可以计算房费 然后退房
        $info = $this->morder->where($where)->find();

        if($info){
            //判断退房金额是否为负 return_money
            $needmoney = $info["return_money"];

            if($needmoney < 0 ){
                $this->error("房费不足，请联系客服处理",[],11); //房费不足
            }elseif($needmoney == 0 ){
                $this->error("房费已抵消，无退款费用",[],12); //押金+基础费用 刚好 抵消房费
                $data["pay_status"] = 3;
                $data["refund_status"] = 0;//申请退款中
            }else{
                try{
                    Db::startTrans();
                    //更新订单状态
                    $refund_number = "refund_".date("YmdHis", time()) . rand(10000000, 99999999);
                    $data["upd_time"] = time();
                    $data["refund_number"] = $refund_number;
                    $data["refund_status"] = 2;//申请退款中
                    $eff1 = $this->morder->where("id={$info['id']}")->update($data);
                    //回归房源状态
                    $rdata["h_statusText"] = "cleaning";
                    $rdata["updatetime"] = time();
                    $eff2 = $this->mhouse->where("id={$info['room_id']}")->update($rdata);

                    if($eff1 && $eff2 ){
                        Db::commit();
                        //返回退款数据

                        $resdata["out_trade_no"] = $info["order_number"]; //订单号
                        $resdata["refund_number"] = $refund_number; //退款号
                        $resdata["return_money"] = $info["return_money"];//退款金额
                        $resdata["all_money"] = $info["all_money"];//总金额
                        $resdata["id"] = $info["id"];//订单id int
                        $resdata["transaction_id"] = $info["transaction_id"];//订单微信流水号

                        $this->success("success",$resdata);
                    }else{
                        Db::rollback();
                        $this->error("退房失败，联系客服");
                    }


                }catch (\think\exception\PDOException $e){
                    $this->error($e->getMessage());
                }
                $this->success("费用计算成功",$info);
            }

        }else{
            $this->error("订单有误");
        }



    }

    public function access_token(){

        //session_start();
        //将access_token存在session/cookie中

        if(isset($_SESSION['access_token'])&&isset($_SESSION['expire_time'])){
            if($_SESSION['expire_time']>time()){

                //如果access_token在session并未过期
                return $_SESSION['access_token'];
            }else{

                //如果access_token不存在或者已经过期，重新获取access_token
                $appid = 'wxd3ed1291e43598cd';
                $appsecret = '3c112f9dced28d11507ea034efa3d099';
                $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$appsecret;
                $res = $this->curl($url,'get','json');

                $access_token=json_decode($res)->{"access_token"};
                //将创新获取的access_token存到session
                $_SESSION['access_token'] = $access_token;
                $_SESSION['expire_time'] = time()+7000;
                $_SESSION['access_token'];
                return $access_token;
            }

        }else{



            //如果access_token不存在或者已经过期，重新获取access_token
            $appid = 'wxd3ed1291e43598cd';
            $appsecret = '3c112f9dced28d11507ea034efa3d099';
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$appsecret;

            $res = $this->curl($url,'get','json');

            $access_token=json_decode($res)->{"access_token"};


            //将创新获取的access_token存到session
            $_SESSION['access_token'] = $access_token;
            $_SESSION['expire_time'] = time()+7000;
            $_SESSION['access_token'];
            return $access_token;
        }
    }


    //消息推送
    public function xiaoxituisong(){

//        $form_id=$request->get("form_id");
//        $openid=$request->get("openid");
        $form_id='123465';
        $openid='olkJA5as0V89Ny9rvcEYDqEF3szE';


        $access_token=$this->access_token();

        $data=[
            "touser"=>$openid, //接收用户的openid
            "template_id"=>"vMwyaONQ0FdYDIMX-ZtgYhe7H2usJBLwbBzdSVxREFo",  //模板id
            "page"=>"pages/index/index",//点击模板消息跳转至小程序的页面
            "form_id"=>$form_id, //可为表单提交时form_id，也可是支付产生的prepay_id
            "data"=>[
                "keyword1"=>[
                    "value"=> "商品名称", //自定义参数
                    "color"=> '#173177'//自定义文字颜色
                ],
                "keyword2"=>[
                    "value"=> "支付金额",//自定义参数
                    "color"=> '#173177'//自定义文字颜色
                ],
                "keyword3"=>[
                    "value"=> "入住时间",//自定义参数
                    "color"=> '#173177'//自定义文字颜色
                ],
                "keyword4"=>[
                    "value"=> "订单号",//自定义参数
                    "color"=> '#173177'//自定义文字颜色
                ],
                "keyword5"=>[
                    "value"=> "温馨提示",//自定义参数
                    "color"=> '#173177'//自定义文字颜色
                ],
            ]
        ];
        $res=$this->SendMsg($data,$access_token); //返回结果
        var_dump($res);
    }


    public static function SendMsg($data,$access_token){
        $MsgUrl="https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=".$access_token; //微信官方接口，需要拼接access_token

        $MsgUrl="https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=".$access_token; //微信官方接口，需要拼接access_token


        return json_decode(self::curl($MsgUrl,$params=json_encode($data),$ispost=1,$https=1)); //访问接口，返回参数
    }

    public static function curl($url, $params = false, $ispost = 0, $https = 0)
    {
        $httpInfo = array();
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
                'Content-Type: application/json; charset=utf-8'
            )
        );
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36');
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        if ($https) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在
        }
        if ($ispost) {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
            curl_setopt($ch, CURLOPT_URL, $url);
        } else {
            if ($params) {
                if (is_array($params)) {
                    $params = http_build_query($params);
                }
                curl_setopt($ch, CURLOPT_URL, $url . '?' . $params);
            } else {
                curl_setopt($ch, CURLOPT_URL, $url);
            }
        }
        $response = curl_exec($ch);
        if ($response === FALSE) {
            return false;
        }
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $httpInfo = array_merge($httpInfo, curl_getinfo($ch));
        curl_close($ch);
        return $response;
    }

    //发送短信

    public function sendduanxin(){

        $mobile = '13770778236';
        $moban='SMS_206741540';

        $param['name']=111;
        $param['jieri']=222;
        $param['time']=333;

//        $this->error('短信签名正在审核中');die;
        $alisms = new \addons\alisms\library\Alisms();

        $ret = $alisms->mobile($mobile)
            ->template($moban)
            ->param($param)
            ->send();
        if ($ret) {
            $this->success(__('发送成功'));
        } else {
            $this->error(__('发送失败，请检查短信配置是否正确'));
        }
    }



    //判断是否填写了手机号
    public function ifmobile(){

        $openid = $this->request->request("openid");
        //根据openid判断是否需要前端发送手机号
        $res = db("user")->where(['openid'=>$openid])->field("phone,openid")->find();

        if($res['phone']){
            $this->success("success",$res);
        }else{
            $this->error("请填写手机号");
        }

    }
    //更新手机号
    public function upmobile(){
        $openid = $this->request->request("openid");
        $phone = $this->request->request("phone");
        if(empty($openid) || empty($phone)){
            $this->error("参数错误");
        }

        $upd['phone'] = $phone;
        if(db("user")->where(['openid'=>$openid])->update($upd)){
            $this->success("手机号更新成功");
        }else{
            $this->error("手机号更新失败");
        }



    }

    public function getmoney(){
        $uid = $this->request->request("uid");
        $m=db('user')->where("id = $uid")->find();

        $this->success('success',$m['money']);
    }


    //退款详情 or 订单详情
    public function order_drawback(){
        $order_number = $this->request->request("order_number");
        $uid = $this->request->request("uid");

        if(empty($order_number) || empty($uid)){
            $this->error("参数错误");
        }

        $where["user_id"] = $uid;
        $where["order_number"] = $order_number;
        $info = $this->morder->where($where)->find();
        $res = model('Config')->where("name='drawbackExplain'")->field("value")->find();
        $res2 = model('Config')->where("name='nopayExplain'")->field("value")->find();
        $res3 = model('Config')->where("name='reserveExplain'")->field("value")->find();
        $res4 = model('Config')->where("name='usingExplain'")->field("value")->find();
        $res5 = model('Config')->where("name='errpayExplain'")->field("value")->find();
        $res6 = model('Config')->where("name='delorderExplain'")->field("value")->find();

        if($info){
            //获取酒店地址信息
            $address = db("hotels")->field("h_address,lng,lat,h_tel")->where(["hid"=>$info["hotelid"]])->find();
            $info["address"] = $address["h_address"];
            $info["lng"] = $address["lng"];
            $info["lat"] = $address["lat"];
            $info["h_tel"] = $address["h_tel"];

            $info["cancel_flag"] = 0; // 1则提示 取消扣费金额
            $info["cancel_money"] = 0;

            //判断订单状态
            if($info["pay_status"] == 0){
                $info["statushtml"] = "订单未支付";
                if($res2){
                    $restmp = $res2->toarray()["value"];
                    if(!empty($restmp)){
                        $info["explain"] = $restmp;
                    }
                }
            }elseif ($info["pay_status"] == 1){
                $info["statushtml"] = "房间已预定，待入住";
                if($res3){
                    $restmp = $res3->toarray()["value"];
                    if(!empty($restmp)){
                        $info["explain"] = $restmp;
                    }
                }

                //判断订单是否免费取消
                $cancelpay_time =  $info["cancelpay_time"];
                $time = time();
                $money = 0 ;
                //判断是否 取消收费
                if($time > $cancelpay_time) {//收费
                    $info["cancel_flag"] = 1; // 1则提示 取消扣费金额



                    $res = model('Config')->where("name='discount'")->field("value")->find();
                    if ($res) {
                        $restmp = $res->toarray()["value"];
                        $orderconfig = json_decode($restmp, true);
                    }
                    if ($orderconfig) {
                        $money = $info["totalprice"] * $orderconfig;
                    } else {
                        $money = $info["totalprice"] * 0.1;
                    }
                    $money = sprintf("%01.2f", $money);
                }

                $info["cancel_money"] = $money;



            }elseif ($info["pay_status"] == 2){
                $info["statushtml"] = "房间已办理入住";
                if($res4){
                    $restmp = $res4->toarray()["value"];
                    if(!empty($restmp)){
                        $info["explain"] = $restmp;
                    }
                }
            }elseif ($info["pay_status"] == 3){
                $info["statushtml"] = "订单已完成";
                if($res){
                    $restmp = $res->toarray()["value"];
                    if(!empty($restmp)){
                        $info["explain"] = $restmp;
                    }
                }
            }elseif ($info["pay_status"] == 4){
                $info["statushtml"] = "订单已取消";
                if($res6){
                    $restmp = $res6->toarray()["value"];
                    if(!empty($restmp)){
                        $info["explain"] = $restmp;
                    }
                }
            }elseif ($info["pay_status"] == 5){
                $info["statushtml"] = "订单支付失败";
                if($res5){
                    $restmp = $res5->toarray()["value"];
                    if(!empty($restmp)){
                        $info["explain"] = $restmp;
                    }
                }
            }else{
                $info["explain"] = "";
                $info["statushtml"] = "订单未知状态";
            }


            $this->success("success",$info);
        }else{
            $this->error("数据获取失败");
        }

    }



    public function wxxmlchongzhi(){
        $testxml = file_get_contents("php://input");
        //将xml转化为json格式
        $jsonxml = json_encode(simplexml_load_string($testxml, 'SimpleXMLElement', LIBXML_NOCDATA));
        //转成数组
        $result = json_decode($jsonxml, true);
        if($result){
            //如果成功返回了
            if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){
                //写入回调日志
                file_put_contents("wxxmlchongzhi.json",var_export($result,true).PHP_EOL,FILE_APPEND);


//               $this->notifyUrl($result['out_trade_no'],$result['sign'],$result['transaction_id'],$result["total_fee"]);
                $openid=$result['openid'];
//                $result['total_fee']=1000;
             $user=db('user')->where("openid = '$openid'")->find();

                $time=time();
                $data['money']=$result['total_fee']/100;
                $data['code1']=$result['transaction_id'];
                $data['code2']=$result['out_trade_no'];
                $data['openid']=$openid;
                $data['uid']=$user['id'];
                $data['ctime']=$time;

                Db::startTrans();
                //在充值表中插入一条记录
                $chongzhi = db('chongzhi')->insert($data);

                if($chongzhi){
                    $data2['user_id']=$user['id'];
                    $data2['money']=$result['total_fee']/100;
                    $data2['before']=$user['money'];
                    $data2['after']=$user['money'] + $result['total_fee']/100;
                    $data2['type']='recharge';
                    $data2['service_ids']=$result['transaction_id'];
                    $data2['createtime']=$time;
                    $data2['memo']='微信余额充值';


                    //在用户行为记录表中插入一条记录
                    $money_log = db('user_money_log')->insert($data2);


                        if($money_log){
                            //更新用户余额
                            $data3['money']=$result['total_fee']/100 + $user['money'];
                            $userupdate=db('user')->where("openid = '$openid'")->update($data3);
                            if($userupdate){


                                //充值返点记录
                                if($result['total_fee']/100 >= 1){
                                    $data4=$data2;
                                    $data4['memo']='充值赠送';
                                    $data4['type']='fs';
                                    $config=db('config')->where("id = 35")->find();
                                    $bili=$config['value'];
                                    $data4['money']= ($result['total_fee']/100)*$bili;
                                    $data4['before']=  $data3['money'];
                                    $data4['after']=  $data3['money']+ ($result['total_fee']/100)*$bili;
                                    $data4['bili']=$bili;
                                    db('user_money_log')->insert($data4);
                                    $data5['money'] = $data4['after'];
                                    db('user')->where("openid = '$openid'")->update($data5);
                                }
                                Db::commit();
                                echo 'success';die;
                            }else{
                                Db::rollback();
                                echo 'success';die;
                            }
                        }else{
                            Db::rollback();
                            echo 'success';die;
                        }
                }else{
                    Db::rollback();
                    echo 'success';die;
                }








                //进行改变订单状态等操作。。。。
            }
        }



    }




    public function wxxml(){

        //获取返回的xml
        $testxml = file_get_contents("php://input");
        //将xml转化为json格式
        $jsonxml = json_encode(simplexml_load_string($testxml, 'SimpleXMLElement', LIBXML_NOCDATA));
        //转成数组
        $result = json_decode($jsonxml, true);
        if($result){
            //如果成功返回了
            if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){
                //写入回调日志
                file_put_contents("wxxml.json",var_export($result,true).PHP_EOL,FILE_APPEND);

                //订单号
                $this->notifyUrl($result['out_trade_no'],$result['sign'],$result['transaction_id'],$result["total_fee"]);

                //进行改变订单状态等操作。。。。
            }
        }
    }

    //支付成功回调 成功后改变房源状态 和 可预定状态
    //判断逻辑，如果用户预定的房间在两个小时以内，那么这个房间立即变成预定状态，其他人不可以预定，
    //如果超过了两个小时，那这个房间的的状态是还是可以空闲状态，但是他的可以预定时间会被记录，其他人只有在这个范围内可以预定，而且 只能预定比这个时间靠前的，不能向后预约，
    //因为 房间预定使用后会有打扫的时间或者维修的时间，以及用户延时的可能，所以，不可以向后预约，后台管理员可以手动调整这个可预定时间。
    //todo 需要一个定时方法自动检测房间的如果到了可预定最晚时间，自动改变房源的状态为预定中，就不可以在被预定了 支付成功 修改积分 和  签名 退款后 在修改回去
    public function notifyUrl($out_trade_no,$sign,$transaction_id,$total_fee){
        //public function notifyUrl(){
        /*  $out_trade_no = $this->request->request("order_number");
          $sign = $this->request->request("sign");
          $transaction_id = $this->request->request("transaction_id");
          $total_fee = $this->request->request("total_fee");*/


        if(empty($out_trade_no)){
            $this->error("参数错误");
        }
        $where["order_number"] = $out_trade_no;
        try{
            $info = $this->morder->where($where)->find()->toArray();



            if($info){

                //开启事物
                Db::startTrans();

                $nowtime = time();
                //更新订单
                $odata["pay_time"] = $nowtime;
                $odata["pay_status"] = 1;
                $odata["upd_time"] = $nowtime;
                $odata["transaction_id"] = $transaction_id;
                $odata["sign"] = $sign;


                //判断预定时间
                if($nowtime  < $info["stime"] - 7200){
                    //两个小时以内 直接改变房源状态
                    $rdata["beforeTime"] = $info["stime"] - 7200;
                }else{
                    //更新房源状态
                    $rdata["h_statusText"] = "reserve";
                    $rdata["beforeTime"] = Null;

                }
                $rdata["updatetime"] = time();


                //支付成功 更新 积分 和 等级

                $uid = $info["user_id"];
                $userinfo = $this->muser->where(["id"=>$uid])->field("id,score,phone,nickName")->find();
                $score = round($total_fee/100, 2);
                $newscore = $userinfo["score"] + $score;
                $eff3= updateLevel($newscore,$uid);//更新积分和等级
                $eff1 = $this->morder->where("id={$info['id']}")->update($odata);
                $eff2 = $this->mhouse->where("id={$info['room_id']}")->update($rdata);

                if($eff1 && $eff2 && $eff3){

                    //回调成功发送用户短信
                    if($userinfo["phone"]){
                        sendUmsg($userinfo["phone"],$info['h_phone']);
                    }
                    //房间预定成功酒店
                    if($userinfo["phone"] && $userinfo["nickName"]){
                        sendHOmsg($userinfo["phone"],$userinfo["nickName"]);
                    }

                    Db::commit();
                    echo 'success';die;
                }else{
                    Db::rollback();
                    echo 'success';die;
                }

            }else{

                $this->error("数据获取失败");
            }


        }catch (\think\exception\PDOException $e){
            $this->error($e->getMessage());
        }

    }




    //退款的回调
    public function refundNotify(){
        $funddata = $this->request->post();
        file_put_contents("refundxml.json",var_export($funddata));


        echo 'success';die;

    }
    //退款开始
    public function submitDrawBack(){
        //通过订单ID，获取订单信息

        $id = $this->request->request("id");
        $out_trade_no=$this->request->param('out_trade_no');
        $refund_number=$this->request->param('refund_number');
        $all_money=$this->request->param('all_money');
        $return_money=$this->request->param('return_money');
        $transaction_id=$this->request->param('transaction_id');
        $openid=$this->request->param('openid');

        if(empty($openid)){
            $this->error("用户参数openid错误");
        }

        //通过微信api进行退款流程
        $nonce_str = WxPay::str_rand();//随机32位字符串


        $total_fee = $all_money * 100;//总金额，单位：分

        //$total_fee= 0.01 * 100;//测试 一分钱

        $refund_fee = $return_money * 100;//退款金额，单位：分

        //$refund_fee= 0.01 * 100;//测试 一分钱

        $parma = array(
            'appid'=> WxPay::appid,
            'mch_id'=> WxPay::mch_id,
            'nonce_str'=> $nonce_str,
            'out_trade_no'=> $out_trade_no,//小程序自定义订单号，支付时后台生成
            'out_refund_no'=> $refund_number,
            'refund_fee'=> $refund_fee,
            'total_fee'=> $total_fee,
            'transaction_id' => $transaction_id,//小程序平台订单号，微信平台生成
        );

        $KEY = WxPay::key;//小程序支付秘钥
//        $parma['sign']  = WxPay::getSignTemp($nonce_str,$openid,$out_trade_no,$total_fee);//签名
        $parma['sign'] = $this->getSign($parma, $KEY);

        $post_xml = $this->arrayToXml($parma);//把参数转化成xml格式

        //向微信平台api发送退款参数
        $xmlresult = $this->postXmlSSLCurl($post_xml,'https://api.mch.weixin.qq.com/secapi/pay/refund');

        //解析返回的参数
        $array = $this->xml2array($xmlresult);
        //两个success表示退款成功，无需使用回调，在此进行逻辑处理即可
        if ($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS') {
            $reData["refund_status"] = 3;

        }else{
            $reData["refund_status"] = 4;
            $this->error("退款失败");
        }
        Db::startTrans();
        //处理退款业务
        $reData["pay_status"] = 3; //已完成
        //退款完成则代表退房 完成后 将房源的状态改成 打扫状态 同时可预定时间置为空 后台也可以手动将 房源改成 打扫 状态
        //这里要注意，如果此房间被另外的用户预定了，那预定时间是不能改变的，所以只要改变房源状态就行；要加上判断
        $orderInfo = db("order")->where(["refund_number"=>$refund_number])->find();
        $roomId = $orderInfo["room_id"];
        //判断是否有预定中的订单
        $rCount = db("order")->where(["pay_status"=>1,"room_id"=>$roomId])->count("id");
        if(!$rCount){
            //不存在预定
            $roomdata['beforeTime'] = Null; //取消 预定时间限制
        }
        $roomdata['h_statusText'] = "cleaning";//打扫
        $roomdata['updatetime'] = time(); //取消 预定时间限制
        $eff3 = db("house")->where(["id"=>$roomId])->update($roomdata);

        $eff = db("order")->where(["id"=>$orderInfo["id"]])->update($reData);

        //退款成功 更新 积分 和 等级
        $userinfo = $this->muser->where(["openid"=>$openid])->field("id,score")->find();
        $newscore = $userinfo["score"] - (float)$return_money;
        $eff2 = updateLevel($newscore,$userinfo['id']);//更新积分和等级

        if($eff && $eff2 && $eff3){
            Db::commit();
            $this->success("退款成功,请查收");
        }else{
            Db::rollback();
            $this->error("退款失败,请联系客服");
        }

    }


    protected function getSign($params, $key)
    {
        ksort($params, SORT_STRING);
        $unSignParaString = $this->formatQueryParaMap($params, false);
        return $signStr = strtoupper(md5($unSignParaString . "&key=" . $key));
    }

    protected function formatQueryParaMap($paraMap, $urlEncode = false)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if (null != $v && "null" != $v) {
                if ($urlEncode) {
                    $v = urlencode($v);
                }
                $buff .= $k . "=" . $v . "&";
            }
        }
        $reqPar = '';
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }


    //数组转字符串方法
    protected function arrayToXml($arr){
        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {

            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }


    //获取xml里面数据，转换成array
    private function xml2array($xml)
    {
        $p = xml_parser_create();
        xml_parse_into_struct($p, $xml, $vals, $index);
        xml_parser_free($p);
        $data = [];

        foreach ($index as $key => $value) {
            if ($key == 'xml' || $key == 'XML') continue;
            $tag = $vals[$value[0]]['tag'];
            $value = $vals[$value[0]]['value'];
            $data[$tag] = $value;
        }
        return $data;
    }
    //需要使用证书的请求
    function postXmlSSLCurl($xml,$url,$second=30)
    {
        //使用的啊里云宝塔，存放证书路径，放在public中，新建cert

        $cert = '/www/wwwroot/minshu/public/cert/apiclient_cert.pem';
        $key = '/www/wwwroot/minshu/public/cert/apiclient_key.pem';
//        $cert = 'C:\Users\Administrator\Desktop\1602911873_20201017_cert/apiclient_cert.pem';
//         $key = 'C:\Users\Administrator\Desktop\1602911873_20201017_cert/apiclient_key.pem';
        $ch = curl_init();
        //超时时间
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        //这里设置代理，如果有的话
        //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //设置证书
        //使用证书：cert 与 key 分别属于两个.pem文件
        //默认格式为PEM，可以注释,使用getcwd()方法，拼接证书的绝对路径
        curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLCERT,$cert);

        //默认格式为PEM，可以注释,使用getcwd()方法，拼接证书的绝对路径
        curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLKEY,$key);

        //post提交方式
        curl_setopt($ch, CURLOPT_POST, true);

        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);

        $data = curl_exec($ch);

//        p($data);die;
        //返回结果
        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            echo "curl出错，错误码:$error" . "<br>";
            curl_close($ch);
            return false;
        }
    }
    //退款结束

    //私有方法类

    //定时房费计算 创建订单时  全日房：存在开始和结束时间，就按照开始时间计费
    //todo暂定：基础服务费不退 只退押金
    protected function computeFeeHour($datainfo){

        $resinfo = [];
        if($datainfo){
            $dayDay = $datainfo["hourDaily"]; //一天多少小时
            $secDay = $datainfo["hourDaily"] * 60 * 60; //一天多少秒
            $priceHour = $datainfo["price"];//每小时的费用
            $oMin = $datainfo["overtimeMinute"];//超过多少分钟算作一小时
            $totalprice = $datainfo["totalprice"];//封顶价
            // $otherMoney = $datainfo["bprice"] + $datainfo["deposit"]; //基础保障费 + 押金
            $otherMoney = $datainfo["deposit"]; //押金
            $otherMoney2 = $datainfo["bprice"]; //基础保障费
            //免费取消时间
            $cancelpay_time = time() + $datainfo["cancelpay_time"] * 60 ; //免费取消房源时间 单位：秒 当前时间 加上 允许时间
            //$cancelpay_time = $datainfo['intstime'] + $datainfo["cancelpay_time"] * 60 ; //免费取消房源时间 单位：秒
            //房间结束前发送短信时间
            $sendmsg_time = $datainfo['intetime'] - $datainfo["sendmsg_time"] * 60 ; //免费取消房源时间 单位：秒


            //计算时间 订单结束时间 减去 开始时间 不考虑入住时间
            $allseconds = $datainfo["intetime"] - $datainfo["intstime"];

            $allHour = floor($allseconds / 3600);  //计算出整小时数
            $allMin = floor(($allseconds - ($allHour * 3600)) / 60); //计算超出的分钟数
            $allSec = ($allseconds - ($allHour * 3600) - ($allMin * 60)); //计算超出的秒数

            if($allseconds < $secDay){
                //未超过一天 按照时薪计算 超过配置的分钟数 按照一小时计算
                if($allMin < $oMin){
                    $fee = $allHour * $priceHour;
                }else{
                    $fee = ($allHour + 1) * $priceHour;
                }
                $resinfo["cancelpay_time"] = $cancelpay_time; //免费取消房源时间 单位：分
                $resinfo["sendmsg_time"] = $sendmsg_time; //免费取消房源时间 单位：秒
                $resinfo["all_price"] = $fee; //房费
                $resinfo["return_money"] = $otherMoney; //退款金额 默认是 押金
                $resinfo["ballprice"] = $datainfo["bprice"]; //如果是一天 基础保障费 和 基础总保障费用 一样
                $resinfo["all_money"] = $otherMoney + $otherMoney2 + $fee; //总费用：基础保障费 + 押金 + 房费  永远实际支付的金额
                $resinfo["income"] = $otherMoney2 + $fee; //收入：基础保障费+房费


            }else{

                //超过 n 天 封顶价 * n 加 超出时间 计算 加 基础保障费 * n 加 1次押金
                $overday = floor($allseconds / $secDay ); //向下取整
                $oversecond = $secDay * $overday;

                $fee = $totalprice * $overday;

                $nowsecond = $allseconds - $oversecond;//剩下的秒数
                $nowHour = floor($nowsecond / 3600);  //计算出整小时数
                $overMin = floor(($nowsecond - ($nowHour * 3600)) / 60); //计算超出的分钟数
                $overSec = ($nowsecond - ($nowHour * 3600) - ($overMin * 60)); //计算超出的秒数

                if($overMin <= $oMin){
                    $fee = $fee + $nowHour * $priceHour;
                }else{
                    $fee = $fee + ($nowHour + 1) * $priceHour;
                }

                $resinfo["cancelpay_time"] = $cancelpay_time; //免费取消房源时间 单位：分
                $resinfo["sendmsg_time"] = $sendmsg_time; //免费取消房源时间 单位：秒
                $resinfo["all_price"] = $fee; //房费
                $resinfo["ballprice"] = $datainfo["bprice"] * $overday; //如果是n天 基础保障费 * n = 基础总保障费用
                $resinfo["return_money"] = $otherMoney; //退款金额 默认是 押金
                $resinfo["all_money"] = $resinfo["ballprice"] + $datainfo["deposit"] + $fee;  //永远实际支付的金额
                $resinfo["income"] = $resinfo["ballprice"] + $fee; //收入：基础保障费+房费

            }

            return $resinfo;

        }else{
            $this->error("计费数据有误");
        }


    }


    //定时订单 退房时 房费计算，主要考虑是否有超时的情况
    protected function computeFeeOrder($orderInfo){

        $res = model('Config')->where("name='ordercofig'")->field("value")->find();
        if($res){
            $restmp = $res->toarray()["value"];
            $orderconfig = json_decode($restmp,true);

        }else{
            $this->error("订单参数配置有误，请联系管理员");
        }

        //当前时间
        $nowtime = time();

        //允许多久延迟退房不计算费用 单位 秒
        $checkoutTime = $orderconfig["允许延迟退房"] ?  $orderconfig["允许延迟退房"] * 3600 : 0;
        $resinfo = [];
        if($orderInfo){
            $dayDay = $orderInfo["hourDaily"]; //一天多少小时
            $secDay = $orderInfo["hourDaily"] * 60 * 60; //一天多少秒
            $priceHour = $orderInfo["price"];//每小时的费用
            $oMin = $orderInfo["overtimeminute"];//超过多少分钟算作一小时
            $totalprice = $orderInfo["totalprice"];//封顶价
            //$otherMoney = $orderInfo["ballprice"] + $orderInfo["deposit"]; //基础保障费 + 押金
            $otherMoney = $orderInfo["deposit"]; // 押金

            //判断是否超时
            if(($nowtime - $checkoutTime) > $orderInfo["etime"]){
                //超时 要判断超时时间 和 计算费用
                //当前时间 与 结束时间 + 允许超时的时间 比较
                $order_second = $nowtime - $orderInfo["etime"] - $checkoutTime; // 订单实时相差秒的时间
                $nowHour = floor($order_second / 3600);  //计算出整小时数
                $overMin = floor(($order_second - ($nowHour * 3600)) / 60); //计算超出的分钟数
                $overSec = ($order_second - ($nowHour * 3600) - ($overMin * 60)); //计算超出的秒数

                if($order_second <= $secDay){
                    //未超过一天 按照时薪计算 超过配置的分钟数 按照一小时计算
                    if($overMin < $oMin){
                        $fee = $nowHour * $priceHour;
                    }else{
                        $nowHour += 1;
                        $fee = $nowHour * $priceHour;
                    }

                    $newsecond = $nowtime - $orderInfo["stime"]; //这里就不考虑超时时间
                    $newHour = floor($newsecond / 3600);  //计算出整小时数
                    $newMin = floor(($newsecond - ($newHour * 3600)) / 60); //计算超出的分钟数
                    $newSec = ($newsecond - ($newHour * 3600) - ($newMin * 60)); //计算超出的秒数

                    $resinfo["all_price"] = $orderInfo["all_price"] + $fee;  //加上之前缴纳的房费
                    $resinfo["over_fee"] = $fee;  //超时费用
                    $resinfo["hour"] = $newHour;  //重新计算时长
                    $resinfo["min"] =  $newMin;
                    $resinfo["second"] = $newSec;
                    $resinfo["return_money"] = $otherMoney - $fee; //退款费用: 押金 - 超时费用
                    $resinfo["all_money"] = $orderInfo["all_money"]; //已缴纳的总费用 第一次缴纳
                    $resinfo["income"] = $orderInfo["income"] + $fee;
                    return $resinfo;

                }else{


                    //超过 n 天 封顶价 * n 加 超出时间 计算 基础保障费 超过多天 也按照一天算 因为 此时 是退款业务，基础保障费本身也要退款，这里就算进去 还是要退回去
                    $overday = floor($order_second / $secDay );
                    $oversecond = $secDay * $overday;
                    $fee = $totalprice * $overday;
                    $nowsecond = $order_second - $oversecond;//剩下的秒数
                    $nowHour = floor($nowsecond / 3600);  //计算出整小时数
                    $overMin = floor(($nowsecond - ($nowHour * 3600)) / 60); //计算超出的分钟数
                    $overSec = ($nowsecond - ($nowHour * 3600) - ($overMin * 60)); //计算超出的秒数

                    if($overMin < $oMin){
                        $fee = $fee + $nowHour * $priceHour;
                    }else{
                        $nowHour += 1;
                        $fee = $fee + $nowHour * $priceHour;
                    }

                    $newsecond = $nowtime - $orderInfo["stime"]; //这里就不考虑超时时间
                    $newHour = floor($newsecond / 3600);  //计算出整小时数
                    $newMin = floor(($newsecond - ($newHour * 3600)) / 60); //计算超出的分钟数
                    $newSec = ($newsecond - ($newHour * 3600) - ($newMin * 60)); //计算超出的秒数

                    $resinfo["all_price"] = $orderInfo["all_price"] + $fee;  //加上之前缴纳的房费
                    $resinfo["over_fee"] = $fee;  //超时费用
                    $resinfo["hour"] = $newHour;  //重新计算时长
                    $resinfo["min"] =  $newMin;
                    $resinfo["second"] = $newSec;
                    $resinfo["return_money"] = $otherMoney - $fee; //退款费用: 押金 - 超时费用
                    $resinfo["all_money"] = $orderInfo["all_money"]; //已缴纳的总费用 第一次缴纳
                    $resinfo["income"] = $orderInfo["income"] + $fee;

                    return $resinfo;
                }



            }else{

                //未超时 订单只要退款 押金 从新计算时长 房费 还是按照预定时长来计算，费用不退 return_money 在创建时已经计算出
                $order_second = $nowtime - $orderInfo["stime"]; // 实际住的时间，退房时间 -  开始时间
                $nowHour = floor($order_second / 3600);  //计算出整小时数
                $overMin = floor(($order_second - ($nowHour * 3600)) / 60); //计算超出的分钟数
                $overSec = ($order_second - ($nowHour * 3600) - ($overMin * 60)); //计算超出的秒数

                $resinfo["hour"] = $nowHour;
                $resinfo["min"] =  $overMin;
                $resinfo["second"] = $overSec;
                $resinfo["return_money"] = $orderInfo["return_money"];

                return $resinfo;
            }



        }else{
            $this->error("订单计费有误");
        }
    }

    //不定时订单 结算计算房费 主要考虑时间和是否押金不够的情况
    protected function computeFeeOrderTwo($orderInfo){
        $resinfo = [];
        if($orderInfo){
            $dayDay = $orderInfo["hourDaily"]; //一天多少小时
            $secDay = $orderInfo["hourDaily"] * 60 * 60; //一天多少秒
            $priceHour = $orderInfo["price"];//每小时的费用
            $oMin = $orderInfo["overtimeminute"];//超过多少分钟算作一小时
            $totalprice = $orderInfo["totalprice"];//封顶价
            $otherMoney = $orderInfo["deposit"]; //基础保障费 + 押金

            //计算时间 当前时间 与 入住时间进行比较 用除法 总有误差 这里才去 乘法比较
            $order_second = time() - $orderInfo["moveinto_time"]; // 订单实时相差秒的时间
            $nowHour = floor($order_second / 3600);  //计算出整小时数

            $overMin = floor(($order_second - ($nowHour * 3600)) / 60); //计算超出的分钟数
            $overSec = ($order_second - ($nowHour * 3600) - ($overMin * 60)); //计算超出的秒数

            if($order_second <= $secDay){
                //未超过一天 按照时薪计算 超过配置的分钟数 按照一小时计算
                if($overMin < $oMin){
                    $fee = $nowHour * $priceHour;
                }else{
                    $nowHour += 1;
                    $fee = $nowHour* $priceHour;
                }

                $resinfo["all_price"] = $fee;
                $resinfo["over_fee"] = $fee;  //时长费用
                $resinfo["hour"] =$nowHour;
                $resinfo["min"] = $overMin;
                $resinfo["second"] = $overSec;
                $resinfo["return_money"] = $otherMoney - $fee; //退款费用:押金 - 时长房费
                $resinfo["all_money"] = $orderInfo["all_money"] + $fee; //已缴纳的总费用 第一次缴纳 + 时长费用
                $resinfo["income"] = $orderInfo["ballprice"] + $fee;

            }else{

                //超过 n 天 封顶价 * n 加 超出时间 计算
                $overday = floor($order_second / $secDay );
                $oversecond = $secDay * $overday;
                $fee = $totalprice * $overday;
                $nowsecond = $order_second - $oversecond;//剩下的秒数
                $nowHour = floor($nowsecond / 3600);  //计算出整小时数
                $overMin = floor(($nowsecond - ($nowHour * 3600)) / 60); //计算超出的分钟数
                $overSec = ($nowsecond - ($nowHour * 3600) - ($overMin * 60)); //计算超出的秒数

                if($overMin <= $oMin){
                    $fee = $fee + $nowHour * $priceHour;
                }else{
                    $nowHour += 1;
                    $fee = $fee + $nowHour * $priceHour;
                }

                $resinfo["all_price"] = $fee;
                $resinfo["over_fee"] = $fee;  //时长费用
                $resinfo["hour"] = $dayDay * $overday + $nowHour;
                $resinfo["min"] = $overMin;
                $resinfo["second"] = $overSec;
                $resinfo["return_money"] = $otherMoney - $fee; //退款费用: 押金 - 时长费用
                $resinfo["all_money"] = $orderInfo["all_money"] + $fee;//已缴纳的总费用 第一次缴纳 + 时长费用
                $resinfo["income"] = $orderInfo["ballprice"] + $fee; //非定时基础保障费用都按照1天计算

            }

            return $resinfo;

        }else{
            $this->error("订单计费有误");
        }
    }

    //检测房源状态 是否可以预定 beforeTime代表可以新预定的最晚时间 支付时，判断可以预定时间，支付后 改变可预定时间
    protected function checkHouseStatus($roomId,$uid,$intetime){
        $where["id"] = $roomId;
        $houseinfo = $this->mhouse->where($where)->find()->toArray();


        if($houseinfo){
            //判断房源状态
            if($houseinfo["h_statusText"] == "normal"){
                //判断用户预定的时间是否允许 是否是同一人
                //判断是否是同一人同房源 未支付 多次下单
                $where2["user_id"] = $uid;
                $where2["room_id"] = $roomId;
                $orderuserinfo = $this->morder->where($where2)->find();

                if($orderuserinfo){
                    if($orderuserinfo["pay_status"] == 0){
                        $this->success("房间待支付，请及时支付",'',5);
                    }elseif ($orderuserinfo["pay_status"] == 1){
                        $this->error("您已经预定了房间，请及时入住");
                    }elseif ($orderuserinfo["pay_status"] == 2){
                        $this->error("您已办理了入住，无需再次预定");
                    }

                }


                //判断是否可以预定房间 如果是没有定时的 就拿第二天12点 为最晚时间来判断是否可以预定，如果不可以 就提示用户选择日期
                if($intetime){
                    if($houseinfo["beforeTime"]){
                        if($intetime >= $houseinfo["beforeTime"]){
                            $this->error(date("d号H时i分",$houseinfo["beforeTime"])."该时段房间已经被预定");
                        }
                    }
                }

                return $houseinfo;

            }elseif ($houseinfo["h_statusText"] == "reserve"){
                $this->error("房间已被预定，稍后再预定");
            }elseif($houseinfo["h_statusText"] == "using"){
                $this->error("房源紧张，被别人抢走了");
            }elseif ($houseinfo["h_statusText"] == "repair"){
                $this->error("房间正在维修，稍后再预定");
            }elseif ($houseinfo["h_statusText"] == "cleaning"){
                $this->error("房间正在打扫，稍后再预定");
            }else{
                $this->error("房间已下架，稍后再预定");
            }

        }else{
            $this->error("未找到房源");
        }

    }







}
